package spe.ui.editor.part;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.NodeEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.jface.viewers.TextCellEditor;

import spe.model.notation.Link;
import spe.ui.editor.command.ElementCellEditorLocator;
import spe.ui.editor.command.ElementDirectEditManager;
import spe.ui.editor.figure.SPEFigure;
import spe.ui.editor.policy.DiagramXYLayoutPolicy;
import spe.ui.editor.policy.ElementComponentEditPolicy;
import spe.ui.editor.policy.ElementDirectEditPolicy;
import spe.ui.editor.policy.SPEMGraphicalNodeEditPolicy;
import spe.model.spem.NodeElement;

public abstract class AbstractElementNodeEditPart extends AbstractGraphicalEditPart implements NodeEditPart, PropertyChangeListener 
{
	public AbstractElementNodeEditPart()
	{
		super();
	}
	
	@Override
	protected void createEditPolicies() 
	{
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new ElementDirectEditPolicy());
		
		//policy for creating link
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new SPEMGraphicalNodeEditPolicy());
		
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new ElementComponentEditPolicy());
	}
	
	@Override
	protected List<Link> getModelSourceConnections()
	{
		return ((NodeElement)getModel()).getLeavingEdges();
	}
	
	@Override
	protected List<Link> getModelTargetConnections()
	{
		return ((NodeElement)getModel()).getArrivingEdges();
	}
	
	@Override
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart edtp)
	{
		return ((SPEFigure)getFigure()).getConnectionAnchor();
	}
	
	@Override
	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart edtp)
	{
		return ((SPEFigure)getFigure()).getConnectionAnchor();
	}
	
	@Override
	public ConnectionAnchor getSourceConnectionAnchor(Request arg0) 
	{
		// TODO Auto-generated method stub
		return ((SPEFigure)getFigure()).getConnectionAnchor();
	}

	@Override
	public ConnectionAnchor getTargetConnectionAnchor(Request arg0) {
		// TODO Auto-generated method stub
		return ((SPEFigure)getFigure()).getConnectionAnchor();
	}

	@Override
	public void performRequest(Request rq)
	{
		 //if this is a request for direct editing
		if(rq.getType() == RequestConstants.REQ_DIRECT_EDIT)
		{
			Label lb = ((SPEFigure)getFigure()).getNameLabel();
			ElementDirectEditManager mgr = new ElementDirectEditManager(this, TextCellEditor.class, new ElementCellEditorLocator(lb), lb);
			mgr.show();
		}
		
		//if user double click on icon
		if(rq.getType() == RequestConstants.REQ_OPEN)
		{
			
		}
	}
	
	@Override
	public void refreshVisuals()
	{
		SPEFigure figure = (SPEFigure)getFigure();
		NodeElement model = (NodeElement)getModel();
		
		GraphEditPart parentPart = (GraphEditPart)getParent(); 
		
		figure.getNameLabel().setText(model.getName());
		
		//System.out.println(String.format("%s, %s, %s", this, figure.getImageSize(), figure.getNameLabel().getTextBounds()));
		
		//Calculate the width of figure
		int w = figure.getImageSize().width > figure.getNameLabel().getTextBounds().width?figure.getImageSize().width:figure.getNameLabel().getTextBounds().width;
		int h = figure.getImageSize().height + figure.getNameLabel().getTextBounds().height + 2;
		Rectangle rect = new Rectangle(model.getPosition(), new Dimension(w, h));
		parentPart.setLayoutConstraint(this, figure, rect);
	}
	
	@Override
	public void activate()
	{
		((NodeElement)getModel()).addPropertyChangeListener(this);
		super.activate();
	}
	
	@Override
	public void deactivate()
	{
		
		((NodeElement)getModel()).removePropertyChangeListener(this);
		super.deactivate();
	}

	@Override
	public void propertyChange(PropertyChangeEvent arg0) 
	{
		// TODO Auto-generated method stub
		refreshVisuals();
		refreshSourceConnections();
		refreshTargetConnections();
	}
}
